package cn.harry.cabinet.server.routes

import cn.harry.cabinet.model.entity.User
import cn.harry.cabinet.repository.UserRepository
import cn.harry.cabinet.server.dto.common.ApiResponse
import cn.harry.cabinet.server.dto.common.PaginationInfo
import cn.harry.cabinet.server.dto.common.PaginationResponse
import cn.harry.cabinet.server.dto.user.UserFormRequest
import cn.harry.cabinet.server.dto.user.UserResponse
import io.ktor.http.HttpStatusCode
import io.ktor.server.application.call
import io.ktor.server.request.receive
import io.ktor.server.response.respond
import io.ktor.server.routing.Route
import io.ktor.server.routing.delete
import io.ktor.server.routing.get
import io.ktor.server.routing.post
import io.ktor.server.routing.put
import io.ktor.server.routing.route
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.InternalSerializationApi

/**
 * 用户API路由
 * 定义用户管理的RESTful API接口
 */
@OptIn(InternalSerializationApi::class)
fun Route.userRoutes(userRepository: UserRepository) {

    route("/api/users") {

        // 获取所有用户
        get {
            try {
                withContext(Dispatchers.IO) {
                    val users = userRepository.getAllUsers()
                    val userResponses = UserResponse.fromUserList(users)

                    call.respond(
                        HttpStatusCode.OK,
                        ApiResponse.success(userResponses, "获取用户列表成功")
                    )
                }
            } catch (e: Exception) {
                call.respondError("获取用户列表失败", e)
            }
        }

        // 根据ID获取用户
        get("/{id}") {
            try {
                val id = call.parameters["id"]?.toLongOrNull()
                if (id == null) {
                    call.respondBadRequest("无效的用户ID")
                    return@get
                }

                withContext(Dispatchers.IO) {
                    val user = findUserById(userRepository, id)
                    if (user == null) {
                        call.respondNotFound("用户不存在")
                        return@withContext
                    }
                    
                    val userResponse = UserResponse.fromUser(user)
                    call.respond(
                        HttpStatusCode.OK,
                        ApiResponse.success(userResponse, "获取用户成功")
                    )
                }
            } catch (e: Exception) {
                call.respondError("获取用户失败", e)
            }
        }

        // 搜索用户 - 支持分页查询
        get("/search") {
            try {
                val query = call.request.queryParameters["query"] ?: ""
                val page = call.request.queryParameters["page"]?.toIntOrNull() ?: 1
                val size = call.request.queryParameters["size"]?.toIntOrNull() ?: 20
                
                // 验证分页参数
                if (page <= 0 || size <= 0 || size > 100) {
                    call.respondBadRequest("分页参数无效：页码必须大于0，每页大小必须在1-100之间")
                    return@get
                }

                withContext(Dispatchers.IO) {
                    // 计算偏移量
                    val offset = (page - 1) * size
                    
                    // 获取搜索结果总数
                    val totalCount = userRepository.getSearchUserCount(query, offset, size)
                    
                    // 获取分页搜索结果
                    val searchResults = userRepository.searchUsersWithPagination(query, offset, size)
                    val userResponses = UserResponse.fromUserList(searchResults)
                    
                    // 计算总页数
                    val totalPages = if (totalCount == 0L) 0L else (totalCount + size - 1) / size
                    
                    // 构建分页响应
                    val paginationInfo = PaginationInfo(
                        page = page,
                        size = size,
                        total = totalCount,
                        totalPages = totalPages
                    )
                    
                    val paginationResponse = PaginationResponse(
                        data = userResponses,
                        pagination = paginationInfo
                    )

                    call.respond(
                        HttpStatusCode.OK,
                        ApiResponse.success(paginationResponse, "搜索用户成功")
                    )
                }
            } catch (e: Exception) {
                call.respondError("搜索用户失败", e)
            }
        }

        // 创建新用户
        post {
            try {
                val request = call.receive<UserFormRequest>()

                // 验证请求数据
                if (!request.isValid()) {
                    val errors = request.getValidationErrors()
                    call.respondBadRequest(errors.joinToString(", "))
                    return@post
                }
                
                // 验证重复字段
                val uniqueErrors = request.validateUniqueFields(userRepository)
                if (uniqueErrors.isNotEmpty()) {
                    call.respondBadRequest(uniqueErrors.joinToString(", "))
                    return@post
                }

                withContext(Dispatchers.IO) {
                    val newUser = User.createNewUser(
                        name = request.name,
                        employeeId = request.employeeId,
                        phoneNumber = request.phoneNumber,
                        position = request.position,
                        gender = request.gender,
                        status = request.status,
                        featureCode = request.featureCode,
                        password = request.password
                    )
                    val createdUser = userRepository.addUser(newUser)
                    
                    val userResponse = UserResponse.fromUser(createdUser)

                    call.respond(
                        HttpStatusCode.Created,
                        ApiResponse.success(userResponse, "创建用户成功")
                    )
                }
            } catch (e: Exception) {
                call.respondError("创建用户失败", e)
            }
        }

        // 更新用户
        put("/{id}") {
            try {
                val id = call.parameters["id"]?.toLongOrNull()
                if (id == null) {
                    call.respondBadRequest("无效的用户ID")
                    return@put
                }

                val request = call.receive<UserFormRequest>()
                
                // 验证请求数据
                if (!request.isValid()) {
                    val errors = request.getValidationErrors()
                    call.respondBadRequest(errors.joinToString(", "))
                    return@put
                }
                
                // 验证重复字段（排除当前用户）
                val uniqueErrors = request.validateUniqueFields(userRepository, id)
                if (uniqueErrors.isNotEmpty()) {
                    call.respondBadRequest(uniqueErrors.joinToString(", "))
                    return@put
                }

                withContext(Dispatchers.IO) {
                    val existingUser = findUserById(userRepository, id)
                    if (existingUser == null) {
                        call.respondNotFound("用户不存在")
                        return@withContext
                    }
                    
                    val updatedUser = existingUser.copy(
                        name = request.name,
                        employeeId = request.employeeId,
                        phoneNumber = request.phoneNumber,
                        position = request.position,
                        gender = request.gender,
                        status = request.status,
                        featureCode = request.featureCode,
                        password = request.password
                    )
                    
                    userRepository.updateUser(updatedUser)
                    
                    val userResponse = UserResponse.fromUser(updatedUser)

                    call.respond(
                        HttpStatusCode.OK,
                        ApiResponse.success(userResponse, "更新用户成功")
                    )
                }
            } catch (e: Exception) {
                call.respondError("更新用户失败", e)
            }
        }

        // 删除用户
        delete("/{id}") {
            try {
                val id = call.parameters["id"]?.toLongOrNull()
                if (id == null) {
                    call.respondBadRequest("无效的用户ID")
                    return@delete
                }

                withContext(Dispatchers.IO) {
                    val userToDelete = findUserById(userRepository, id)
                    if (userToDelete == null) {
                        call.respondNotFound("用户不存在")
                        return@withContext
                    }
                    
                    userRepository.deleteUser(userToDelete)
                    call.respond(HttpStatusCode.OK, ApiResponse.success(message = "删除用户成功"))
                }
            } catch (e: Exception) {
                call.respondError("删除用户失败", e)
            }
        }
    }
}

/**
 * 私有扩展函数：根据ID查找用户
 */
private suspend fun findUserById(userRepository: UserRepository, id: Long): User? {
    return userRepository.getUserById(id)
}

/**
 * 私有扩展函数：响应错误请求
 */
@OptIn(InternalSerializationApi::class)
private suspend fun io.ktor.server.application.ApplicationCall.respondBadRequest(message: String) {
    respond(
        HttpStatusCode.BadRequest,
        ApiResponse.errorResponse(400, message)
    )
}

/**
 * 私有扩展函数：响应未找到错误
 */
@OptIn(InternalSerializationApi::class)
private suspend fun io.ktor.server.application.ApplicationCall.respondNotFound(message: String) {
    respond(
        HttpStatusCode.NotFound,
        ApiResponse.errorResponse(404, message)
    )
}

/**
 * 私有扩展函数：响应服务器错误
 */
@OptIn(InternalSerializationApi::class)
private suspend fun io.ktor.server.application.ApplicationCall.respondError(message: String, exception: Exception) {
    // 添加更详细的错误日志
    println("$message: ${exception.javaClass.simpleName} - ${exception.message}")
    exception.printStackTrace()
    
    respond(
        HttpStatusCode.InternalServerError,
        ApiResponse.errorResponse(500, "$message: ${exception.message}")
    )
} 